// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Jeff Stewart
//
// Displays a progress screen as tests run.

#include <QtGui/QScrollArea>
#include <QtGui/QGridLayout>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QDialog>
#include <QtGui/QFileDialog>

#include "ui/progressscreen.h"
#include "ui/browser.h"
#include "ui/support.h"
#include "ui/wizard.h"
#include "util/provider.h"
#include "probes/smtpprobe.h"

namespace popdiag {

ProgressScreen::ProgressScreen(QWidget *app)
    : QWizardPage(app), complete_(false),
      progress_(new QProgressBar(this)),
      prolog_(new Browser(this, QSize(400, 150))),
      config_log_(),
      executive_(NULL) {
}

ProgressScreen::~ProgressScreen() {
}

void ProgressScreen::SetupUI() {
  QVBoxLayout *layout = new QVBoxLayout(this);
  setLayout(layout);
  QString banner = "<h1>";
  banner.append(tr("Step 2/2: Running Tests",
                   "The third step of the wizard"));
  banner.append("</h1><p></p>");
  QLabel *bannerlabel = new QLabel(this);
  bannerlabel->setText(banner);
  bannerlabel->setWordWrap(true);
  layout->addWidget(bannerlabel);
  layout->addWidget(prolog_);
  progress_->setOrientation(Qt::Horizontal);
  progress_->setMinimum(0);
  progress_->setMaximum(0);
  layout->addWidget(progress_);
}

void ProgressScreen::initializePage() {
  SetComplete(false);
  const QString email = wizard()->field("email").toString();
  const QString pass = wizard()->field("password").toString();
  const QString imap_server = wizard()->field("imapServer").toString();
  const QString pop_server = wizard()->field("popServer").toString();
  const QString smtp_server = wizard()->field("smtpServer").toString();
  int smtp_port = wizard()->field("smtpPort").toString().toInt();
  bool pull_all_mail = wizard()->field("fetchAllMail").toBool();

  QString text = "<p>";
  text += tr("We are now running tests %1.",
             "Explains that tests are running in the background.")
          .arg(email);
  if (provider->HasSupportLinks()) {
    text += " <a href=\"";
    text += provider->GetSupportLink(Support::TESTS_RUNNING) + "\">";
    text += tr("Learn more", "A label for a hyperlink that will open "
              "a browser and display additional external "
              "help text about this tool.");
    text += "</a>";
  }
  text += "<br>";
  if (!pull_all_mail) {
    text += tr("This should take less than a minute.",
               "Asks the user to be patient.");
  } else {
    text += tr("This may take several minutes.",
               "Asks the user to be patient.");
  }
  text += "</p>";
  text += "<p>";
  text += tr("Checking server access...", "A status message");
  text += "</p>";
  prolog_->setHtml(text);
  ExecutiveOptions options;
  options.username = email;
  options.password = pass;
  options.imap_server = imap_server;
  options.pop_server = pop_server;
  options.smtp_server = smtp_server;
  options.smtp_port = smtp_port;
  options.pull_all_mail = pull_all_mail;
  options.config_log = config_log_;
  executive_.reset(new Executive(NULL, options));
  CHECK(connect(executive_.get(), SIGNAL(ProgressMade(int, int)),
                this, SLOT(OnProgressMade(int, int))));
  CHECK(connect(executive_.get(), SIGNAL(ReportReady()),
                this, SLOT(WriteReportToDesktop())));
  CHECK(connect(executive_.get(), SIGNAL(Done()),
                this, SLOT(OnExecutiveDone())));
  executive_->Start();
}

void ProgressScreen::ClientConfigLogs(const QString &log) {
  config_log_ = log;
}

void ProgressScreen::cleanupPage() {
  if (executive_ != NULL) {
    executive_->Abort();
    executive_.reset(NULL);
  }
  SetComplete(false);
}

bool ProgressScreen::isComplete() const {
  return complete_;
}

void ProgressScreen::SetComplete(bool newval) {
  if (newval != complete_) {
    complete_ = newval;
    emit completeChanged();
  }
  if (newval) {
    CHECK(executive_ != NULL);
    ProbeSet *probes = executive_->probes();
    CHECK(probes != NULL);
    ProbeSet::Storage probe_info;
    probes->GetProbes(&probe_info);
    emit TestsComplete(probe_info);
    wizard()->next();
  }
}

void ProgressScreen::WriteReportToDesktop() {
  if (executive_ == NULL) {
    // happens when the user clicks "back" while tests are running.
    return;
  }
  QDir home = QDir::home();
  QString desktop_path = home.filePath("Desktop");
  QDir desktop(desktop_path);
  QString target_path;
  const QString kLogname = "PopImapTroubleshooterLog.html";
  if (desktop.exists()) {
    target_path = desktop.filePath(kLogname);
  } else {
    target_path = home.filePath(kLogname);
  }
  QFile file(target_path);
  if (file.open(QIODevice::Truncate | QIODevice::WriteOnly)) {
    file.write(executive_->GetReport().toUtf8());
    file.close();
    emit ReportWrittenToDesktop(target_path);
  }
}

void ProgressScreen::OnProgressMade(int progress_made, int estimated_total) {
  progress_->setMaximum(estimated_total);
  progress_->setValue(progress_made);
}

void ProgressScreen::OnExecutiveDone() {
  SetComplete(true);
}

}  // namespace popdiag
